package com.huifaapp.mall.selectImage;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.media.ExifInterface;
import android.provider.MediaStore.Images.Media;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.HashMap;

public class BitmapCondense {
    private static String MEDIA_COLUMNS[] = new String[]{Media.DATA, Media._ID, Media.TITLE, Media.DISPLAY_NAME};

    public static final HashMap<String, String> mFileTypes = new HashMap<String, String>();

    static {
        mFileTypes.put("FFD8FF", "jpg");
        mFileTypes.put("89504E47", "png");
        mFileTypes.put("47494638", "gif");
    }

    public BitmapCondense() {
    }

    ;


    /**
     * 将缩放之后的图片缩放成要求的大小
     *
     * @param reqWidth
     * @param reqHeight
     * @return
     */
    public static Bitmap getAdaptiveBitmap(InputStream stream, int reqWidth, int reqHeight) {
        if (stream == null) {
            return null;
        }
        Bitmap bitmap = decodeSampledBitmapFromStream(stream, reqWidth, reqHeight);
        if (bitmap == null) {
            return null;
        }
        final int width = bitmap.getWidth();
        final int height = bitmap.getHeight();
        int resWidth = width;
        int resHeight = height;
        if (resWidth > reqWidth) {
            float simpleSize = (float) reqWidth / resWidth;
            resWidth = (int) (resWidth * simpleSize);
            resHeight = (int) (resHeight * simpleSize);
        }
        if (resHeight > reqHeight) {
            float simpleSize = (float) reqHeight / resHeight;
            resWidth = (int) (resWidth * simpleSize);
            resHeight = (int) (resHeight * simpleSize);
        }
        return Bitmap.createScaledBitmap(bitmap, resWidth, resHeight, true);
    }

    /**
     * 将缩放之后的图片缩放成要求的大小
     *
     * @param res
     * @param resId
     * @param reqWidth
     * @param reqHeight
     * @return
     */
    public static Bitmap getAdaptiveBitmap(Resources res, int resId, int reqWidth, int reqHeight) {
        if (res == null || resId <= 0) {
            return null;
        }
        Bitmap bitmap = decodeSampledBitmapFromResource(res, resId, reqWidth, reqHeight);
        if (bitmap == null) {
            return null;
        }
        final int width = bitmap.getWidth();
        final int height = bitmap.getHeight();
        int resWidth = width;
        int resHeight = height;
        if (resWidth > reqWidth) {
            float simpleSize = (float) reqWidth / resWidth;
            resWidth = (int) (resWidth * simpleSize);
            resHeight = (int) (resHeight * simpleSize);
        }
        if (resHeight > reqHeight) {
            float simpleSize = (float) reqHeight / resHeight;
            resWidth = (int) (resWidth * simpleSize);
            resHeight = (int) (resHeight * simpleSize);
        }
        return Bitmap.createScaledBitmap(bitmap, resWidth, resHeight, true);
    }

    /**
     * 将缩放之后的图片缩放成要求的大小
     *
     * @param path
     * @param reqWidth
     * @param reqHeight
     * @return
     */
    public static Bitmap getAdaptiveBitmap(String path, int reqWidth, int reqHeight) {
        if (TextUtils.isEmpty(path)) {
            return null;
        }
        Bitmap bitmap = decodeSampledBitmapFromPath(path, reqWidth, reqHeight);
        if (bitmap == null) {
            return null;
        }
        final int width = bitmap.getWidth();
        final int height = bitmap.getHeight();
        int resWidth = width;
        int resHeight = height;
        if (resWidth > reqWidth) {
            float simpleSize = (float) reqWidth / resWidth;
            resWidth = (int) (resWidth * simpleSize);
            resHeight = (int) (resHeight * simpleSize);
        }
        if (resHeight > reqHeight) {
            float simpleSize = (float) reqHeight / resHeight;
            resWidth = (int) (resWidth * simpleSize);
            resHeight = (int) (resHeight * simpleSize);
        }
        return Bitmap.createScaledBitmap(bitmap, resWidth, resHeight, true);
    }

    /**
     * 计算图片的缩放比例
     *
     * @param options
     * @param reqWidth
     * @param reqHeight
     * @return
     */
    private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
            while ((halfHeight / inSampleSize) > reqHeight || (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }
        return inSampleSize;
    }

    /**
     * 得到缩放后的图片，得到的图片始终比要求的宽度和高度大或相等，防止OOM
     *
     * @param res
     * @param resId
     * @param reqWidth
     * @param reqHeight
     * @return
     */
    public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
    }

    /**
     * 得到缩放后的图片，得到的图片始终比要求的宽度和高度大或相等，防止OOM
     *
     * @param reqWidth
     * @param reqHeight
     * @return
     */
    public static Bitmap decodeSampledBitmapFromPath(String path, int reqWidth, int reqHeight) {
        if (TextUtils.isEmpty(path)) {
            return null;
        }
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(path, options);
    }

    /**
     * 得到缩放后的图片，得到的图片始终比要求的宽度和高度大或相等，防止OOM
     *
     * @param reqWidth
     * @param reqHeight
     * @return
     */
    public static Bitmap decodeSampledBitmapFromStream(InputStream is, int reqWidth, int reqHeight) {
        if (is == null) {
            return null;
        }
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(is, new Rect(0, 0, reqWidth, reqHeight), options);
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeStream(is, new Rect(0, 0, reqWidth, reqHeight), options);
    }

    /**
     * 根据路径获取指定大小的图片
     *
     * @param bitmapwidth
     * @param bitmapheight
     * @param file
     * @return
     */
    public static Bitmap Condense(int bitmapwidth, int bitmapheight, String file) {
        File f = new File(file);
        if (file == null || !f.exists())
            return null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(file, options);
        options.inSampleSize = calculateInSampleSize(options.outWidth, options.outHeight, bitmapwidth, bitmapheight);
        options.inJustDecodeBounds = false;
        // return BitmapFactory.decodeFile(file, options);
        return ExifRotationDegree(BitmapFactory.decodeFile(file, options), file);
    }

    /**
     * 根据路径获取指定縮放比例的图片
     *
     * @return
     */
    public static int calculateInSampleSize(int nowWidth, int nowHeight, int reqWidth, int reqHeight) {
        final int height = nowHeight;
        final int width = nowWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }
        // if (width > height) {
        // inSampleSize = Math.round((float) height / (float) reqHeight);
        // } else {
        // inSampleSize = Math.round((float) width / (float) reqWidth);
        // }
        // }
        // if (inSampleSize % 2 == 1) {
        // inSampleSize += 1;
        // }
        return inSampleSize;
    }

    public Bitmap SavePicInLocal(Bitmap bitmap, int BitmapSize) {
        ByteArrayOutputStream baos = SavePicIn(bitmap, BitmapSize);
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
        bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
        return bitmap;
    }

    /**
     * 压缩图片到指定的大小
     *
     * @param bitmap
     * @param BitmapSize 图片的指定大小：单位 : byte
     * @return
     */
    public static ByteArrayOutputStream SavePicIn(Bitmap bitmap, int BitmapSize) {
        if (bitmap == null) {
            return null;
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        int options = 100;
        while (baos.toByteArray().length > BitmapSize * 1024) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
            baos.reset();// 重置baos即清空baos
            bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%，把压缩后的数据存放到baos中
            options -= 10;// 每次都减少10
            if (options <= 0)
                break;
        }
        return baos;
    }

    // 将流压轉換图片
    public Bitmap ToBitmap(Bitmap bitmap, int BitmapSize) {
        ByteArrayInputStream isBm = new ByteArrayInputStream(SavePicIn(bitmap,
                BitmapSize).toByteArray());
        return BitmapFactory.decodeStream(isBm, null, null);
    }

    /**
     * 将dip转化为像素
     *
     * @param context
     * @param dip
     * @return
     */
    public static int DIPtoPX(Context context, int dip) {
        return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip,
                context.getResources().getDisplayMetrics());
    }

    /**
     * 判断图片的类型
     *
     * @param path
     * @return
     */
    public static boolean isGif(String path) {
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(path);
            byte[] bt = new byte[3];
            fileInputStream.read(bt);
            String s = new String(bt, "utf-8");
            if (s.equals("gif") || s.equals("GIF")) {
                return true;
            } else {
                return false;
            }
        } catch (FileNotFoundException e) {
            return false;
        } catch (IOException e) {
            return false;
        } finally {
            try {
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
            } catch (IOException e) {
            }
        }
    }

    public static int ExifRotationDegree(String path) {
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int Degree = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
            switch (Degree) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    Degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    Degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    Degree = 270;
                    break;
                default:
                    Degree = 0;
            }
            return Degree;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return 0;
        }
    }

    public static Bitmap ExifRotationDegree(Bitmap bitmap, String path) {
        if (bitmap == null) {
            return null;
        }
        int Degree = ExifRotationDegree(path);
        Matrix m = new Matrix();
        m.setRotate(Degree, (float) bitmap.getWidth() / 2, (float) bitmap.getHeight() / 2);
        Bitmap bm1 = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
        return bm1;
    }

    public static void ExifRotationDegree(Bitmap bitmap, String path, ImageView imageView) {
        if (bitmap == null) {
            return;
        }
        Bitmap bm1 = ExifRotationDegree(bitmap, path);
        imageView.setImageBitmap(bm1);
    }

    public static void ExifRotationDegree(int width, int height, String path, ImageView imageView) {
        Bitmap bm1 = ExifRotationDegree(Condense(width, height, path), path);
        if (bm1 == null) {
            return;
        }
        imageView.setImageBitmap(bm1);
    }

    public static Bitmap ExifRotationDegree(int width, int height, String path) {
        Bitmap bm1 = ExifRotationDegree(Condense(width, height, path), path);
        if (bm1 == null) {
            return null;
        }
        return bm1;
    }

    public static void getmem_UNUSED(Context mContext) {
        long MEM_UNUSED;
        // 得到ActivityManager
        ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
        // 创建ActivityManager.MemoryInfo对象

        ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
        am.getMemoryInfo(mi);

        // 取得剩余的内存空间
        MEM_UNUSED = mi.availMem;
        System.out.println("MEM_UNUSED" + MEM_UNUSED + "-----------------------");
    }

    public static int getScreenHeight(Context context) {
        WindowManager windowManager = (WindowManager) context.getSystemService(Activity.WINDOW_SERVICE);
        DisplayMetrics metrics = new DisplayMetrics();
        windowManager.getDefaultDisplay().getMetrics(metrics);
        return metrics.heightPixels;
    }

    public static int getScreenWidth(Context context) {
        WindowManager windowManager = (WindowManager) context.getSystemService(Activity.WINDOW_SERVICE);
        DisplayMetrics metrics = new DisplayMetrics();
        windowManager.getDefaultDisplay().getMetrics(metrics);
        return metrics.widthPixels;
    }

    public static int[] getLocation(View v) {
        int[] location = new int[2];
        v.getLocationInWindow(location);
        return location;
    }

    public static int getLocationX(View v) {
        return getLocation(v)[1];
    }

    public static int getLocationY(View v) {
        return getLocation(v)[1];
    }

    /**
     * 计算原始图片的宽高
     *
     * @param path
     */
    public static int[] computOriginalSize(String path) {
        if (TextUtils.isEmpty(path)) {
            return null;
        }
        int[] size = new int[2];
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(path, options);
        size[0] = options.outWidth;
        size[1] = options.outHeight;
        return size;
    }

    /**
     * 计算缩略图的宽高
     *
     * @param reqW
     * @return
     */
    public static int[] computThumSize(String path, int reqW) {
        if (TextUtils.isEmpty(path)) {
            return null;
        }
        int[] original = computOriginalSize(path);
        int[] thum = new int[2];
        int w = original[0];
        int h = original[1];
        float scale = reqW / (float) w;
        if (scale >= 1) {
            return original;
        } else {
            thum[0] = reqW;
            thum[1] = (int) (h * scale + 0.5f);
            return thum;
        }
    }

    /**
     * 根据原图的宽高计算缩略图的宽高
     *
     * @param size
     * @return
     */
    public static int[] computThumSize(int[] size, int reqW) {
        if (size == null) {
            return null;
        }
        int[] original = size;
        int[] thum = new int[2];
        int w = original[0];
        int h = original[1];
        float scale = reqW / (float) w;
        if (scale >= 1) {
            return original;
        } else {
            thum[0] = reqW;
            thum[1] = (int) (h * scale + 0.5f);
            return thum;
        }
    }

    /**
     * 返回SD卡中的所有图片，如果SD卡不存在则返回null
     *
     * @return
     */
    public static ArrayList<String> querySDcardPicture(Context context) {
        if (!RootFile.checkSdCardState()) {
            return null;
        }
        ArrayList<String> pics = new ArrayList<String>();
        Cursor cursor = context.getContentResolver().query(Media.EXTERNAL_CONTENT_URI, MEDIA_COLUMNS, null, null, Media.DATE_ADDED + " desc");
        if (cursor == null) {
            return pics;
        }
        while (cursor.moveToNext()) {
            String pic = cursor.getString(cursor.getColumnIndex(Media.DATA));
            if (!new File(pic).exists()) {
                continue;
            }
            pics.add(pic);
        }
        cursor.close();
        return pics;
    }

    /**
     * 将要读取文件头信息的文件的byte数组转换成string类型表示
     *
     * @param src 要读取文件头信息的文件的byte数组
     * @return 文件头信息
     */
    private static String bytesToHexString(byte[] src) {
        StringBuilder builder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        String hv;
        for (int i = 0; i < src.length; i++) {
            // 以十六进制（基数 16）无符号整数形式返回一个整数参数的字符串表示形式，并转换为大写
            hv = Integer.toHexString(src[i] & 0xFF).toUpperCase();
            if (hv.length() < 2) {
                builder.append(0);
            }
            builder.append(hv);
        }
        return builder.toString();
    }

    /**
     * 　　* 根据文件路径获取文件头信息
     * 　　*
     * 　　* @param filePath
     * 　　*            文件路径
     * 　　* @return 文件头信息
     *
     */
    public static String getFileHeader(String filePath) {
        FileInputStream is = null;
        String value = null;
        try {
            is = new FileInputStream(filePath);
            byte[] b = new byte[4];
            is.read(b, 0, b.length);
            value = bytesToHexString(b);
            is.close();
        } catch (Exception e) {
        }

        return value;
    }

    /**
     * 　* 根据文件路径获取文件头信息
     * 　*
     * 　*@param filePath
     * 　*            文件路径
     * 　* @return 文件头信息
     *
     */
    public static String getFileType(String filePath) {
        return mFileTypes.get(getFileHeader(filePath));
    }

    /**
     * 拷贝文件
     *
     * @param newPath
     * @param oldPath
     */
    public static boolean copy(String newPath, String oldPath) {
        FileInputStream fi = null;
        FileOutputStream fo = null;
        FileChannel in = null;
        FileChannel out = null;
        try {
            fi = new FileInputStream(oldPath);
            fo = new FileOutputStream(newPath);
            in = fi.getChannel();
            out = fo.getChannel();
            in.transferTo(0, in.size(), out);
            return true;
        } catch (Exception e) {
            return false;
        } finally {
            try {
                fo.close();
                in.close();
                out.close();
                fi.close();
            } catch (IOException e) {
            }
        }
    }

    public static boolean addWaterMarkToImage(Context context, String inputPath, String outputPath, Bitmap mark){
        if(mark == null){
            return false;
        }
        Bitmap bitmap = decodeSampledBitmapFromPath(inputPath, getScreenWidth(context), getScreenHeight(context));
        if(bitmap == null){
            return false;
        }
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        Bitmap result = Bitmap.createBitmap(width, height, bitmap.getConfig());
        Canvas canvas = new Canvas(result);
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        canvas.drawBitmap(bitmap, 0, 0, paint);
        int markW = mark.getWidth();
        if(markW > (width / 5F)){
            float scale = width / 10F / markW;
            Rect src = new Rect(0, 0, mark.getWidth(), mark.getHeight());
            int dstW = (int) (width / 10F + 0.5F);
            int dstH = (int) (mark.getHeight() * scale + 0.5F);
            Rect dst = new Rect(width - dstW - 10, 10, width - 10, 10 + dstH);
            canvas.drawBitmap(mark, src, dst, paint);
        } else {
            canvas.drawBitmap(mark, width - markW - 10, 10, paint);
        }

        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(outputPath);
            result.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
            return true;
        } catch (FileNotFoundException e) {
            return false;
        } finally {
            try {
                if(outputStream != null){
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 保存bitmap到本地
     * @param mBitmap
     * @return
     */
    public static String saveBitmap(Bitmap mBitmap, String fileName) {
        String savePath = RootFile.getXyCacheFiles().getPath();
        File filePic;
        try {
            filePic = new File(savePath + fileName);
            if (!filePic.exists()) {
                filePic.getParentFile().mkdirs();
                filePic.createNewFile();
            }
            FileOutputStream fos = new FileOutputStream(filePic);
            mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }

        return filePic.getAbsolutePath();
    }
}
